#include "driver_key.h"
#include "driver_led.h"
#include "tick.h"
#include "main.h"
extern Indicator indicators[4];

void buttonInit(Button *buttons, uint8_t size)
{

  GPIO_InitTypeDef GPIO_Key_InitConfig;

  Key1_GPIO_CLK_ENABLE();
  Key2_GPIO_CLK_ENABLE();

  GPIO_Key_InitConfig.Mode = GPIO_MODE_INPUT;
  GPIO_Key_InitConfig.Pull = GPIO_PULLUP;
  GPIO_Key_InitConfig.Speed = GPIO_SPEED_FREQ_HIGH;
  // printf("length:%d, %d, %d\r\n\r\n\r\n\r\n", sizeof(buttons), sizeof(buttons[0]), size);
  for (int i = 0; i < size; i++)
  {
    /* Key GPIO */
    GPIO_Key_InitConfig.Pin = buttons[i].pin;
    HAL_GPIO_Init(buttons[i].GPIOx, &GPIO_Key_InitConfig);
  }
}

// 按键扫描函数
void buttonScan(Button *buttons, uint8_t size)
{
  for (int i = 0; i < size; i++)
  {
    bool is_pressed = buttons[i].readIO(buttons[i].GPIOx, buttons[i].pin);
    if (btIndicatorMode == 0)
    {
      if (!is_pressed)
      {
        indicators[buttons[i].id - 1].state = INDICATOR_OFF;
        indicators[buttons[i].id - 1].isLedOn = 1;
      }
    }

    switch (buttons[i].state)
    {
    case BUTTON_RELEASED:
      if (is_pressed)
      {
        buttons[i].lastChangeTime = millis();
        buttons[i].state = BUTTON_PRESSED;
        if (btIndicatorMode == 0)
        {
          indicators[buttons[i].id - 1].state = INDICATOR_ON;
          indicators[buttons[i].id - 1].isLedOn = 1;
        }
      }
      else
      {
      }
      break;
    case BUTTON_PRESSED:
      if (!is_pressed)
      {
        if (millis() - buttons[i].lastChangeTime < buttons[i].shortPressTime)
        {
          buttons[i].state = BUTTON_SHORT_PRESSED;
          buttons[i].lastChangeTime = millis(); //
        }
        else
        {
          buttons[i].state = BUTTON_RELEASED;
        }
        if (btIndicatorMode == 0)
        {
          indicators[buttons[i].id - 1].state = INDICATOR_OFF;
          indicators[buttons[i].id - 1].isLedOn = 1;
        }
      }
      else if (millis() - buttons[i].lastChangeTime >= buttons[i].longPressTime)
      {
        buttons[i].state = BUTTON_LONG_PRESSED;
        buttons[i].onLongPress(millis() - buttons[i].lastChangeTime, buttons[i].id);
      }
      break;
    case BUTTON_SHORT_PRESSED:
      buttons[i].onShortPress(buttons[i].id);
      // ("BUTTON_RELEASED, changed time: %ld, interval: %d\r\n", millis() - buttons[i].lastShortPressTime, buttons[i].multiPressInterval);
      if (millis() - buttons[i].lastShortPressTime <= buttons[i].multiPressInterval)
      {
        buttons[i].pressCount++;
        buttons[i].state = BUTTON_MULTI_PRESSING;
      }
      else
      {
        buttons[i].pressCount = 1;
      }
      buttons[i].lastShortPressTime = millis();
      if (!is_pressed && buttons[i].state != BUTTON_MULTI_PRESSING)
      {
        buttons[i].state = BUTTON_RELEASED;
        if (btIndicatorMode == 0)
        {
          indicators[buttons[i].id - 1].state = INDICATOR_OFF;
          indicators[buttons[i].id - 1].isLedOn = 1;
        }
      }
      break;
    case BUTTON_LONG_PRESSED:
      if (!is_pressed)
      {
        buttons[i].state = BUTTON_RELEASED;
        if (btIndicatorMode == 0)
        {
          indicators[buttons[i].id - 1].state = INDICATOR_OFF;
          indicators[buttons[i].id - 1].isLedOn = 1;
        }
      }
      else
      {
        buttons[i].onLongPress(millis() - buttons[i].lastChangeTime, buttons[i].id);
      }
      break;
    case BUTTON_MULTI_PRESSING:
      if (!is_pressed)
      {
        if (buttons[i].pressCount > 1)
        {
          buttons[i].onMultiPress(buttons[i].pressCount, buttons[i].id);
        }
        buttons[i].state = BUTTON_RELEASED;
        if (btIndicatorMode == 0)
        {
          indicators[buttons[i].id - 1].state = INDICATOR_OFF;
          indicators[buttons[i].id - 1].isLedOn = 1;
        }
      }
      break;
    }
  }
}

bool readPin(GPIO_TypeDef *GPIOx, uint8_t pin)
{
  return HAL_GPIO_ReadPin(GPIOx, pin) == KEY_DOWN;
}
